#include "stdafx.h"
#include "Aspector.h"
#include "ProceedingJoinPoint.h"

CAspector::CAspector()
{
}

CAspector CAspector::instance;
Vtlb CAspector::aspectInstallerVtlb;

ASPECTOR_API 
CAspector* CAspector::Instance()
{
	return &instance;
}

void CAspector::InstallAdvices(void *_pObject,const type_info& type)
{
	CAspectorObject* pObject = reinterpret_cast<CAspectorObject*>(_pObject);
	Vtlb* vtlb = pObject->pVtbl;
	objects.insert(
		std::make_pair(
			pObject,
			std::make_pair((type_info*)&type,vtlb)));
	pObject->pVtbl = &aspectInstallerVtlb;
}

int CAspector::Invoke(CAspectorObject* pObject,int vtlbIndex,va_list parametersStack)
{
	std::pair<type_info*,Vtlb*> pair = objects[pObject];
	CProceedingJoinPoint joinPoint(pObject,
		vtlbIndex,
		parametersStack,
		pair.first,
		pair.second);
	ExecuteBeforeAdvices(joinPoint);
	int returnValue = 0;
	try
	{
		returnValue = ExecuteAroundAdvices(joinPoint);
	}
	catch(...)
	{
		ExecuteThrowAdvices(joinPoint);
		throw;
	}
	return ExecuteAfterAdvices(joinPoint,returnValue);
}


